/*
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package top.continew.admin.hanfu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import top.continew.admin.common.util.OssIdClearUtils;
import top.continew.admin.hanfu.core.oss.OSS;
import top.continew.admin.hanfu.domain.Active;
import top.continew.admin.hanfu.domain.ActiveTable;
import top.continew.admin.hanfu.domain.OssFile;
import top.continew.admin.hanfu.domain.Participants;
import top.continew.admin.hanfu.domain.bo.ActiveBo;
import top.continew.admin.hanfu.domain.dto.ActiveDto;
import top.continew.admin.hanfu.domain.vo.ActiveDeVo;
import top.continew.admin.hanfu.domain.vo.ActiveListVo;
import top.continew.admin.hanfu.domain.vo.ActiveVo;
import top.continew.admin.hanfu.domain.vo.wx.ActiveDeWxVo;
import top.continew.admin.hanfu.domain.vo.wx.ActiveWxVo;
import top.continew.admin.hanfu.mapper.ActiveMapper;
import top.continew.admin.hanfu.service.IActiveService;

import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author bbm
 * @since 2025-03-30
 */
@Service
@RequiredArgsConstructor
public class ActiveServiceImpl extends ServiceImpl<ActiveMapper, Active> implements IActiveService {

    private final ActiveMapper activeMapper;

    private final ActiveTableServiceImpl tableService;

    private final String SUBJECT = "active";

    private final OSS oss;

    private final ParticipantsServiceImpl participantsService;

    public ActiveDto createActive(ActiveBo bo) {

        Active active = BeanUtil.copyProperties(bo, Active.class);

        active.setUpdateTime(System.currentTimeMillis() + "");
        active.setStatus(3);

        save(active);

        return BeanUtil.copyProperties(active, ActiveDto.class);
    }

    @Override
    public Page<ActiveListVo> getActiveListVo(ActiveBo bo, Integer pageNum, Integer pageSize) {
        return activeMapper.getActiveListVo(new Page<>(pageNum, pageSize), bo);
    }

    @Override
    public ActiveVo getActiveDeById(Integer id) {
        return activeMapper.getActiveByid(id);
    }

    @Override
    public ActiveDeVo getActiveDeVo(ActiveBo activeBo) {
        //查询数据表id
        ActiveTable one = tableService.lambdaQuery().eq(ActiveTable::getActiveId, activeBo.getId()).one();

        if (one == null) {
            return null;
        }

        return activeMapper.getActiveDeVo(activeBo.getId(), one.getId());
    }

    @Override
    public ActiveDto putActive(ActiveBo bo) {

        boolean update = lambdaUpdate().set(!bo.getActiveTitle().isEmpty(), Active::getActiveTitle, bo.getActiveTitle())
            .set(!bo.getActiveStartTime().isEmpty(), Active::getActiveStartTime, bo.getActiveStartTime())
            .set(!bo.getActiveDeadline().isEmpty(), Active::getActiveDeadline, bo.getActiveDeadline())
            .set(!bo.getActiveAddr().isEmpty(), Active::getActiveAddr, bo.getActiveAddr())
            .set(!bo.getActiveLabel().isEmpty(), Active::getActiveLabel, bo.getActiveLabel())
            .set(bo.getActivePrice() != null, Active::getActivePrice, bo.getActivePrice())
            .set(bo.getActiveOriginPrice() != null, Active::getActiveOriginPrice, bo.getActiveOriginPrice())

            .set(!bo.getActiveAim().isEmpty(), Active::getActiveAim, bo.getActiveAim())
            .set(!bo.getActiveTrip().isEmpty(), Active::getActiveTrip, bo.getActiveTrip())

            .set(!bo.getActiveTargetGroup().isEmpty(), Active::getActiveTargetGroup, bo.getActiveTargetGroup())
            .set(!bo.getActiveRegisterDeadline().isEmpty(), Active::getActiveRegisterDeadline, bo
                .getActiveRegisterDeadline())
            .set(bo.getActiveLimit() != null, Active::getActiveLimit, bo.getActiveLimit())
            .set(!bo.getActiveTargetGroup().isEmpty(), Active::getActiveTargetGroup, bo.getActiveTargetGroup())

            .set(Active::getStatus, bo.getStatus())
            .set(!bo.getActiveInstance().isEmpty(), Active::getActiveInstance, bo.getActiveInstance())

            .set(Active::getUpdateBy, bo.getUpdateBy())
            .set(Active::getUpdateTime, System.currentTimeMillis() + "")

            .eq(Active::getId, bo.getId())
            .update();
        return BeanUtil.copyProperties(bo, ActiveDto.class);
    }

    @Override
    public Integer putActiveHeadImg(ActiveBo bo) {

        StringBuilder ossIds = new StringBuilder();

        Active byId = getById(bo.getId());

        if (byId.getActiveHeadImg() != null && !byId.getActiveHeadImg().isEmpty()) {
            List<String> oldOssIds = Arrays.stream(byId.getActiveHeadImg().split(",")).toList();
            List<String> newOssIds = Arrays.stream(bo.getActiveHeadImgOssIds().split(",")).toList();

            List<String> delOssIds = oldOssIds.stream().filter(i -> {
                return !newOssIds.contains(i);
            }).toList();

            oss.deleteFiles(delOssIds);

            newOssIds.forEach(i -> {
                ossIds.append(i).append(",");
            });

        }

        if (bo.getActiveHeadImg().get(0).getSize() != 0) {
            List<OssFile> ossFiles = oss.saveFile(SUBJECT + "head_img", bo.getUpdateBy(), bo.getActiveHeadImg()
                .toArray(new MultipartFile[] {}));

            ossFiles.forEach(i -> {
                ossIds.append(i.getOssId()).append(",");
            });

        }

        ossIds.delete(ossIds.length() - 1, ossIds.length());

        boolean update = lambdaUpdate()

            .set(Active::getActiveHeadImg, OssIdClearUtils.cleanFrontCover(ossIds.toString()))

            .set(Active::getUpdateBy, bo.getUpdateBy())
            .set(Active::getUpdateTime, System.currentTimeMillis())

            .eq(Active::getId, bo.getId())
            .update();

        return update ? 1 : 0;
    }

    @Override
    public Integer putActiveInstance(ActiveBo bo) {

        Active byId = getById(bo.getId());

        List<String> list = new java.util.ArrayList<>(Arrays.stream(byId.getActiveInstance().split(",")).toList());

        list.remove(bo.getActiveInstance());

        oss.deleteFile(Integer.parseInt(bo.getActiveInstance()));

        StringBuilder ossIds = new StringBuilder();

        list.forEach(i -> {
            ossIds.append(i).append(",");
        });

        ossIds.delete(ossIds.length() - 1, ossIds.length());

        boolean update = lambdaUpdate().set(Active::getActiveInstance, ossIds.toString())
            .set(Active::getUpdateBy, bo.getUpdateBy())
            .set(Active::getUpdateTime, System.currentTimeMillis())
            .eq(Active::getId, bo.getId())
            .update();

        return update ? 1 : 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer delActive(ActiveBo activeBo) {

        Active byId = getById(activeBo.getId());

        //删除大图
        String activeHeadImg = byId.getActiveHeadImg();

        if (activeHeadImg != null) {

            List<String> list = Arrays.stream(activeHeadImg.split(",")).toList();

            oss.deleteFiles(list);

        }

        //删除实例
        String activeInstance = byId.getActiveInstance();

        if (activeInstance != null) {

            List<String> list = Arrays.stream(activeInstance.split(",")).toList();

            oss.deleteFiles(list);

        }

        //删除活动表单
        ActiveTable one = tableService.lambdaQuery().eq(ActiveTable::getActiveId, byId.getId()).one();

        boolean b = tableService.removeById(one.getId());

        if (!b) {
            throw new RuntimeException("删除活动表单失败");
        }

        //删除嘉宾信息
        List<Participants> list = participantsService.lambdaQuery().eq(Participants::getActiveId, byId.getId()).list();

        list.forEach(i -> {
            String participantsAvatar = i.getParticipantsAvatar();

            oss.deleteFile(Integer.parseInt(participantsAvatar));

        });

        if (list.size() != 0) {
            boolean b2 = participantsService.removeBatchByIds(list);

            if (!b2) {
                throw new RuntimeException("删除嘉宾信息失败");
            }
        }

        boolean b1 = removeById(byId.getId());

        if (!b1) {
            throw new RuntimeException("删除活动失败");
        }

        return 1;
    }

    @Override
    public ActiveDeWxVo getActiveDeWxVo(ActiveBo activeBo) {

        //查询数据表id
        ActiveTable one = tableService.lambdaQuery().eq(ActiveTable::getActiveId, activeBo.getId()).one();

        if (one == null) {
            return null;
        }

        return activeMapper.getActiveDeWxVo(activeBo.getId(), one.getId());
    }

    @Override
    public Page<ActiveWxVo> getActiveWxVoPage(ActiveBo activeBo, Integer pageNum, Integer pageSize) {

        return activeMapper.getActiveWxVo(new Page<>(pageNum, pageSize), activeBo);
    }

}
